# 工具链配置 - 使用 riscv64-unknown-elf- 前缀
CROSS_COMPILE ?= riscv64-unknown-elf-
CC := $(CROSS_COMPILE)gcc
LD := $(CROSS_COMPILE)ld
OBJCOPY := $(CROSS_COMPILE)objcopy
OBJDUMP := $(CROSS_COMPILE)objdump

# 目标文件名
KERNEL_ELF = kernel.elf
KERNEL_BIN = kernel.bin

# 源码文件 (需要根据你的实际项目结构调整)
SRCS = entry.S start.c uart.c  console.c printf.c ansi.c string.c number.c vm.c test_mem.c spinlock.c pmm.c# 添加你的其他 .c 和 .S 文件
OBJS = $(SRCS:.c=.o)
OBJS := $(OBJS:.S=.o)

# 编译和链接标志
CFLAGS += -march=rv64imafdc -mabi=lp64d -mcmodel=medany
CFLAGS += -Wall -Wextra -O2 -fno-omit-frame-pointer -ggdb
CFLAGS += -ffreestanding -nostdlib -fno-pic -fno-stack-protector
CFLAGS += -I. -MD

LDFLAGS += -z max-page-size=4096 -nostdlib -static

# 默认目标
all: $(KERNEL_ELF) $(KERNEL_BIN)

# 链接内核，使用 kernel.ld 链接脚本
$(KERNEL_ELF): $(OBJS) kernel.ld
	$(LD) $(LDFLAGS) -T kernel.ld -o $@ $(OBJS)
	@echo ">> OBJDUMP 生成内核反汇编代码 kernel.asm..."
	$(OBJDUMP) -S $@ > kernel.asm
	@echo ">> NM 生成内核符号表 kernel.sym..."
	$(CROSS_COMPILE)nm $@ | sort > kernel.sym

# 生成原始的二进制镜像（有时用于直接加载）
$(KERNEL_BIN): $(KERNEL_ELF)
	$(OBJCOPY) -S -O binary $< $@

# 编译 C 源文件
%.o: %.c
	$(CC) $(CFLAGS) -c -o $@ $<

# 编译汇编源文件
%.o: %.S
	$(CC) $(CFLAGS) -c -o $@ $<

# 包含自动生成的依赖文件
-include $(OBJS:.o=.d)

# 启动 QEMU 模拟器
QEMU = qemu-system-riscv64
QEMUOPTS = -machine virt -bios none -kernel $(KERNEL_ELF) -m 128M -smp 1 -nographic

qemu: $(KERNEL_ELF)
	$(QEMU) $(QEMUOPTS)
qemu-gdb: $(kernel)
	qemu-system-riscv64 -machine virt -bios none -kernel kernel.elf -m 128M -smp 1 -nographic -s -S

# 支持调试的 QEMU 启动选项
QEMUOPTS_DEBUG = $(QEMUOPTS) -s -S
qemu-debug: $(KERNEL_ELF)
	$(QEMU) $(QEMUOPTS_DEBUG)

# 清理构建产物
clean:
	rm -f *.o *.d *.elf *.bin *.asm *.sym

.PHONY: all clean qemu qemu-debug
